[bits 32]
%define ERROR_CODE  nop
%define ZERO        push 0

extern put_str
extern intr_table

section .data
; intr_str    db  "interrupt occur!", 0xa, 0
global intr_entry_table
intr_entry_table:

%macro VECTOR   2
section .text
intr_%1_entry:
    %2
    ; 接下来会调用c语言的函数 所以我们要先入栈
    ; pushad只会入栈所有32位寄存器
    
    push ds
    push es
    push fs
    push gs
    pushad

    ; 由于我们开启的是手动清除eoi模式
    ; 所以要向ocw2写入清除命令
    mov dx, 0xa0
    mov al, 0x20
    out dx,al
    mov dx, 0x20
    mov al, 0x20
    out dx, al

    ; 目前不知道什么原因进入中断后if标志位不自动清0
    ; 具体原因见global.h
    ; cli
    ; 传入中断号参数
    push %1
    ; 调用c语言中的中断处理函数
    call [intr_table + %1 * 4]
    
    ; 中断退出
    jmp intr_exit

    

; 将每个函数入口地址放到intr_entry_table数组里面
; 编译器会将节属性相同的合并为段
section .data
    dd intr_%1_entry
%endmacro

section .text
global intr_exit
intr_exit:
    add esp, 4

    popad
    pop gs
    pop fs
    pop es
    pop ds
    

    ; 跳过Error code
    add esp, 4
    ; 因为上面手动清零了 所以这里要开启if
    ; 具体原因见global.h
    ; sti

    iretd


VECTOR 0x00,ZERO
VECTOR 0x01,ZERO
VECTOR 0x02,ZERO
VECTOR 0x03,ZERO 
VECTOR 0x04,ZERO
VECTOR 0x05,ZERO
VECTOR 0x06,ZERO
VECTOR 0x07,ZERO 
VECTOR 0x08,ERROR_CODE
VECTOR 0x09,ZERO
VECTOR 0x0a,ERROR_CODE
VECTOR 0x0b,ERROR_CODE 
VECTOR 0x0c,ZERO
VECTOR 0x0d,ERROR_CODE
VECTOR 0x0e,ERROR_CODE
VECTOR 0x0f,ZERO 
VECTOR 0x10,ZERO
VECTOR 0x11,ERROR_CODE
VECTOR 0x12,ZERO
VECTOR 0x13,ZERO 
VECTOR 0x14,ZERO
VECTOR 0x15,ZERO
VECTOR 0x16,ZERO
VECTOR 0x17,ZERO 
VECTOR 0x18,ERROR_CODE
VECTOR 0x19,ZERO
VECTOR 0x1a,ERROR_CODE
VECTOR 0x1b,ERROR_CODE 
VECTOR 0x1c,ZERO
VECTOR 0x1d,ERROR_CODE
VECTOR 0x1e,ERROR_CODE
VECTOR 0x1f,ZERO 
VECTOR 0x20,ZERO    ;时钟中断
VECTOR 0x21,ZERO    ;键盘中断
VECTOR 0x22,ZERO    ;级联
VECTOR 0x23,ZERO    ;串口2
VECTOR 0x24,ZERO    ;串口1
VECTOR 0x25,ZERO    ;并口2
VECTOR 0x26,ZERO    ;软盘
VECTOR 0x27,ZERO    ;并口1
VECTOR 0x28,ZERO    ;实时时钟
VECTOR 0x29,ZERO    ;重定向
VECTOR 0x2a,ZERO    ;保留
VECTOR 0x2b,ZERO    ;保留
VECTOR 0x2c,ZERO    ;ps/2鼠标
VECTOR 0x2d,ZERO    ;fpu浮点单元异常
VECTOR 0x2e,ZERO    ;硬盘
VECTOR 0x2f,ZERO    ;保留

